#include "mq135.h"
#include "stm32f10x.h"
#include "usart.h"
#include "math.h"

uint16_t ADCConvertedValue[10] = {0};   //保存ADC1 DMA数据

				  
static void Gpio_Init()
{
    GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_ADC1 |RCC_APB2Periph_GPIOC ,ENABLE );
	
    //GPIOC.1    channel_11
    GPIO_InitStructure .GPIO_Mode =GPIO_Mode_AIN;
	GPIO_InitStructure .GPIO_Pin =GPIO_Pin_1 ;
    GPIO_Init (GPIOC, &GPIO_InitStructure );
	
}

static void ADC_MODE_CONFIG_(void)
{ 	
	
	DMA_InitTypeDef DMA_InitInstructure;
    ADC_InitTypeDef ADC_InitStructure; 
    
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

	DMA_DeInit(DMA1_Channel1);//复位
	DMA_InitInstructure.DMA_PeripheralBaseAddr =((uint32_t)ADC1 + 0x4C) ;//配置外设的基址，取adc 
	DMA_InitInstructure.DMA_MemoryBaseAddr = (u32)ADCConvertedValue;//把DMA的数据存入数组
	DMA_InitInstructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到DMA
	DMA_InitInstructure.DMA_BufferSize = 10;
	DMA_InitInstructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//
	DMA_InitInstructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitInstructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	DMA_InitInstructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_InitInstructure.DMA_Mode = DMA_Mode_Circular;//不断地传输，有数据就传输
	DMA_InitInstructure.DMA_Priority = DMA_Priority_High;//DMA优先级
	DMA_InitInstructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel1,&DMA_InitInstructure);
	DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA请求
	

	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立 
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在多通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;	//模数转换工作在连续转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是 
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   
 
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
    
    //设置指定ADC的规则组通道，一个序列，采样时间
    //ADC1,ADC1通道1,采样时间为239.5周期
	ADC_RegularChannelConfig(ADC1, ADC_Channel_11,1, ADC_SampleTime_239Cycles5 );	 

 
    ADC_DMACmd(ADC1,ENABLE);	
    ADC_Cmd(ADC1,ENABLE);
 
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
//	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
 
 
}				  

void MQ135_Init()
{
   Gpio_Init();
   ADC_MODE_CONFIG_();
}



/**
  * @brief  MQ135输出电压值
  * @param  None
  * @retval 电压值
  */
float GetMQ135Out(void)
{
    uint8_t i;
    uint16_t adcvalue = 0;
    double volt = 0;
    double ppm = 0;

	for (i = 0; i < 10; i++)
    {
        adcvalue+=ADCConvertedValue[i];

    }
    adcvalue /= 10;
//    printf("adcvalue = %d.\n",adcvalue);
    volt=(double)adcvalue*(3.3/4096);
//    printf("volt = %f.\n",volt);
    
    ppm = pow((3.4880*10*volt)/(5-volt),(1.0/0.3203));
//    printf("ppm = %f.\n\n",ppm);

    return ppm;
}




